package com.gopay.bis.service.bank.impl.expay;

import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;

import com.gopay.bis.common.util.BankLogUtils;
import com.gopay.bis.common.util.constants.BisPayConstants;
import com.gopay.bis.manager.bank.expay.PabExPayManager;
import com.gopay.bis.service.bank.BankOrderService;
import com.gopay.bis.service.bank.sms.SmsSupportController;
import com.gopay.common.Result;
import com.gopay.common.constants.bank.PabConstants;
import com.gopay.common.constants.bank.SmsConstants;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.cps.manager.order.CpsGeneralMainOrderQueryManager;
import com.gopay.common.domain.bank.ExPayBaseMessage;
import com.gopay.common.domain.bank.pab.expay.PabExPayMessage;
import com.gopay.common.domain.bank.pab.expay.res.PabExPayFastpayCPRes;
import com.gopay.common.domain.bank.pab.expay.res.PabExPayFastpayFPARes;
import com.gopay.common.domain.bank.pab.expay.res.PabExPayFastpaySOQResFather;
import com.gopay.common.exception.GopayException;
import com.gopay.remote.bank.ExPayInteractRemoteService;

public class PabExPayServiceImpl implements ExPayInteractRemoteService {

	private static Logger logger = LoggerFactory.getLogger(PabExPayServiceImpl.class);
	
	@Resource(name = "pabExPayManager")
	private PabExPayManager pabExPayManager;
	
	// 短信验证码处理类
    public SmsSupportController smsController;
    
    @Resource(name = "bankOrderService")
	private BankOrderService bankOrderService;
    
    @Resource(name = "cpsGeneralMainOrderQueryManager")
	private CpsGeneralMainOrderQueryManager mainOrderQuery;
	
	/**
	 * 在此为客户验证
	 */
	@Override
	public Result sign(ExPayBaseMessage baseMsg) {
		 return null;
	}

	@Override
	public Result payment(ExPayBaseMessage baseMsg) {
		Result result = new Result(false);
		PabExPayMessage message = new PabExPayMessage();
        BeanUtils.copyProperties(baseMsg, message);
        Map<String, String> param = new HashMap<String, String>();
        
        try {
        	Result res = (Result) pabExPayManager.payment(message);
        	result.setDefaultModel(res.get("ISVERIFY"));
        	if((boolean)res.get("ISVERIFY")){
           		if(res.isSuccess()){
           		// 验签成功
           			PabExPayFastpayCPRes resMsg = (PabExPayFastpayCPRes)res.get("RES");
           			
                    param.put("orderId", resMsg.getSerialNo());
                    param.put("amt", message.getAmount().toString());
                    param.put("cardType", "Unknown");
                    param.put("notifyNum", "1");
                    param.put("payStatus", "00");
                    param.put("retCode", "00");
                    param.put("retMsg", "支付成功");
                    param.put("isFront", String.valueOf(false));
                    result.setModel("isNotifyCashier", param);
                    result.setOrderStatus(true);	
                    
                    
           		} else {
           		// 通知后台地址该订单失败
                    param.put("orderId", baseMsg.getOrderId());
                    param.put("amt", baseMsg.getAmount().toString());
                    param.put("cardType", "Unknown");
                    param.put("notifyNum", "1");
                    param.put("payStatus", "01");
                    param.put("retCode", "01");
                    param.put("retMsg", StringUtils.isEmpty(res.getErrorMsg()) ? "支付失败" : res.getErrorMsg());
                    param.put("isFront", String.valueOf(false));
                    result.setModel("isNotifyCashier", param);
                    result.setOrderStatus(false);	  
                    result.setBankRetCode(res.getBankRetCode());// 快捷API失败通知
                    
           		}
       		} else {
       		// 通知后台地址该订单失败
                param.put("orderId", baseMsg.getOrderId());
                param.put("amt", baseMsg.getAmount().toString());
                param.put("cardType", "Unknown");
                param.put("notifyNum", "1");
                param.put("payStatus", "01");
                param.put("retCode", "01");
                param.put("retMsg", "验签失败");
                param.put("isFront", String.valueOf(false));
                result.setModel("isNotifyCashier", param);
                result.setOrderStatus(false);
                result.setBankRetCode("VERIFY_ERROR");// 快捷API失败通知  
       		}
        	//将token号存入bis_bank_main_order,方便后面对单和退款的时候能查询到token号
            String tokenNo = pabExPayManager.getTokenNo(message);
            baseMsg.setBankReturnOrderId(tokenNo);
        	result.setSuccess(true);
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6057);
		}
        return result;
	}
	
	@Override
	public Result queryOrder(ExPayBaseMessage baseMsg) {
		Result result = new Result(false);
		PabExPayMessage message = new PabExPayMessage();
        BeanUtils.copyProperties(baseMsg, message);
        
        Map<String, String> param = new HashMap<String, String>();
        try {
        	
			Result res = (Result) pabExPayManager.query(message);
			result.setDefaultModel(res.get("ISVERIFY"));
        	if((boolean)res.get("ISVERIFY")){
        		if(res.isSuccess()){
        			PabExPayFastpaySOQResFather resMsg = (PabExPayFastpaySOQResFather)res.get("RES");
        			result.setModel("RES", resMsg);
        			if(PabConstants.EXPAY_QUERY_RESP_STATUS_SUCCESS.equals(resMsg.getStatus())){
        				// 成功处理
    					param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
    					param.put("tradeState", BisPayConstants.TRADESTATE_SUCCESS);
    					param.put("returnMessage", "交易成功");
    					
    					result.setOrderStatus(true);
    					result.setModel("flag", true);
        			}else if(PabConstants.EXPAY_QUERY_RESP_STATUS_FAIL.equals(resMsg.getStatus())){
        				//处理失败
        				param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
    					param.put("tradeState", BisPayConstants.TRADESTATE_FAIL);
    					param.put("returnMessage", "交易失败");
    					
    					result.setOrderStatus(false);
    					result.setModel("flag", false);
        			}else{
        				//处理中
        				param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
    					param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
    					param.put("returnMessage", "银行订单正在处理中");
        			}
        		}else{
        			//失败
        			param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
					param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
					param.put("returnMessage", "银行订单正在处理中");
        		}
        	}else{
        		//验签失败
        		param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
				param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
				param.put("returnMessage", "银行验签失败");
				
				result.setOrderStatus(false);
				result.setModel("flag", false);
        	}
        	
        	result.setSuccess(true);    
		}  catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
			result.setOrderStatus(false);
			result.setModel("flag", false);
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setOrderStatus(false);
			result.setModel("flag", false);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6058);
		} 
        return result;
	}
	
	
	@Override
	public Result verify(ExPayBaseMessage baseMsg) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Result treatyQuery(ExPayBaseMessage baseMsg) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Result cancel(ExPayBaseMessage baseMsg) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Result refund(ExPayBaseMessage msg) {
		Result result = new Result(false); 
		PabExPayMessage message = new PabExPayMessage();
        BeanUtils.copyProperties(msg, message);
		Map<String, String> param = new HashMap<String, String>();
		//平安银行不支持当天退款，所以如果是当天的支付单子，要等到第二天才能退款
		/*if(DateUtils.isToday(msg.getSpecial4())){
			result.setModel("flag", true);
   			result.setErrorMsg("平安快捷只能次日退款，等待至次日发送报文！");
   			logger.error("平安快捷只能次日退款，等待至次日发送报文！");
   			return result;
		}*/
        try {
        	Result res = (Result) pabExPayManager.refund(message);
        	result.setDefaultModel(res.get("ISVERIFY"));
       		if((boolean)res.get("ISVERIFY")){
           		if(res.isSuccess()){
           			// 成功处理
					result.setModel("flag", true);
           		} else {
           			result.setModel("flag", true);
           			result.setErrorMsg("平安快捷退款失败！");
           		}
       		} else {
       			//验签失败
        		param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
				param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
				param.put("returnMessage", "银行验签失败");
				
				result.setOrderStatus(false);
				result.setModel("flag", false);
				result.setErrorMsg("验签失败！");
       		}
        	
            result.setSuccess(true);
        } catch (GopayException e) {
            BankLogUtils.printServiceImplExceptionLog(e);
            result.setResultCode(e.getErrCode());
        } catch (Exception e) {
            BankLogUtils.printServiceImplExceptionLog(e);
            result.setResultCode(ProcCodeConstants.PROC_CODE_100E6087);
        }
        return result;
	}


    @Override
    public Result certification(ExPayBaseMessage baseMsg) {
        Result result = new Result(false);
        PabExPayMessage message = new PabExPayMessage();
        BeanUtils.copyProperties(baseMsg, message);
        Map<String, String> param = new HashMap<String, String>();
        try {
    	   Result res = (Result) pabExPayManager.certification(message);
    	   result.setDefaultModel(res.get("ISVERIFY"));
       		if((boolean)res.get("ISVERIFY")){
           		if(res.isSuccess()){
           			// 成功处理
					result.setModel("flag", true);
					
					//鉴权成功以后要把银行返回的token号记录下来
					PabExPayFastpayFPARes fpaRes = (PabExPayFastpayFPARes)res.getModel("RES");
					String tokenNo = fpaRes.getTokenNo();
					logger.error("鉴权成功，银行返回的token号：" + tokenNo);
					pabExPayManager.recordTokenNo(message, tokenNo);
           		} else {
           			result.setModel("flag", false);
           			result.setErrorMsg(res.getErrorMsg());
           		}
       		} else {
       			//验签失败
        		param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
				param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
				param.put("returnMessage", "银行验签失败");
				
				result.setOrderStatus(false);
				result.setModel("flag", false);
				result.setErrorMsg("验签失败！");
       		}
           result.setSuccess(true);      
       } catch (GopayException e) {
           BankLogUtils.printServiceImplExceptionLog(e);
           result.setResultCode(e.getErrCode());
       } catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E1147);
		}
       return result;
    }

    @Override
    public Result sendSms(ExPayBaseMessage baseMsg) {
        Result result = new Result(false);
        PabExPayMessage message = new PabExPayMessage();
        BeanUtils.copyProperties(baseMsg, message);
        try {
        	//暂时注释，用来测试
        	Map<String, String> smsRes = smsController.sendSMS(message);
            if (ProcCodeConstants.PROC_CODE_100E6102.equals(smsRes.get("resCode"))) {
                // 短信发送成功
                result.setModel("flag", true);
            } else {
                // 短信发送失败
                result.setModel("flag", false);
            }
            result.setModel("sendCount", smsRes.get("sendCount"));
            result.setModel("retMsg", smsRes.get("retMsg"));
            result.setModel("resCode", smsRes.get("resCode"));
            result.setResultCode(smsRes.get("resCode"));
            result.setSuccess(true);
        	
            
            /*result.setModel("flag", true);
	        result.setModel("sendCount", "0");
	        result.setModel("retMsg", "短信发送成功");
	        result.setModel("resCode", ProcCodeConstants.PROC_CODE_100E6102);
	        result.setResultCode(ProcCodeConstants.PROC_CODE_100E6102);
	        result.setSuccess(true);*/
            
            
        } catch (Exception ex) {
            BankLogUtils.printServiceImplExceptionLog(ex);
            result.setResultCode(ProcCodeConstants.PROC_CODE_100E6077);
        }
        return result;
    }

    /**
     * 验证短信请求
     */
    @Override
    public Result checkSms(ExPayBaseMessage baseMsg) {
        Result result = new Result(false);
        PabExPayMessage message = new PabExPayMessage();
        BeanUtils.copyProperties(baseMsg, message);
        try {
        	Map<String, String> smsRes = smsController.checkSMS(message);
            if (ProcCodeConstants.PROC_CODE_100E6091.equals(smsRes.get("resCode"))) {
                // 验证通过
                result.setModel("flag", true);               
            } else {
                // 验证失败
                result.setModel("flag", false);
                if(!ProcCodeConstants.PROC_CODE_100E6099.equals(smsRes.get("resCode"))){
                    Map<String, String> freezeRes = smsController.freezeCard(message);
                    if(freezeRes != null)
                        smsRes = freezeRes;
                }
            }
            result.setModel("failCount", smsRes.get("failCount"));
            result.setModel("retMsg", smsRes.get("retMsg"));
            result.setModel("resCode", smsRes.get("resCode"));
            result.setResultCode(smsRes.get("resCode"));
            result.setSuccess(true);
            
          //**************start
            /*result.setModel("flag", true);
            result.setModel("failCount", "0");
            result.setModel("resCode", ProcCodeConstants.PROC_CODE_100E6091);
            result.setModel("retMsg", SmsConstants.CHECKSMS_SUCCESS);
            result.setSuccess(true);*/
            //**************end
        } catch (Exception ex) {
            BankLogUtils.printServiceImplExceptionLog(ex);
            result.setResultCode(ProcCodeConstants.PROC_CODE_100E6078);
        }
        return result;
    }

    @Override
    public Result queryCvn(ExPayBaseMessage baseMsg) {
    	return null;
    }
    


    public void setPabExPayManager(PabExPayManager pabExPayManager) {
		this.pabExPayManager = pabExPayManager;
	}

	public SmsSupportController getSmsController() {
        return smsController;
    }

    public void setSmsController(SmsSupportController smsController) {
        this.smsController = smsController;
    }

	/*@Override
	public Result pay(BaseMessage base) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Result bankBack(BaseMessage base) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Result queryBack(BaseMessage base) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Result query(BaseMessage base) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Result refund(BaseMessage base) {
		 return null;
	}

	@Override
	public Result dayend(BaseMessage base) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Result refundBack(BaseMessage base) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Result refundQuery(BaseMessage base) {
		Result result = new Result(false);
		PabExPayMessage message = new PabExPayMessage();
        BeanUtils.copyProperties(base, message);
        try {
            
            SignFastpaySOQRes res = (SignFastpaySOQRes) pabExPayManager.query(message);
            SignMessageSOQRes msg= res.getMessage();
            if(msg!=null&&msg.getSOQresFather()!=null){
                PabExPayFastpaySOQResFather resMsg = msg.getSOQresFather();
                result.setDefaultModel(resMsg);
            }
        	
        	
        	result.setSuccess(true);    
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		}  
        return result;
	}

	@Override
	public Result sendBankRefund(BaseMessage base) {
		// TODO Auto-generated method stub
		return null;
	}*/

	@Override
	public Result queryNeedCert(ExPayBaseMessage baseMsg) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Result refundBack(ExPayBaseMessage baseMsg) {
		// TODO Auto-generated method stub
		return null;
	}
}
